home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / editors / mutt / me2s_pl7.zoo / mu_edit2 / mc2 / token.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-26  |  9.3 KB  |  369 lines

  1. /* 
  2.  * token.c : piddle with tokens
  3.  */
  4.  
  5. /* Copyright 1990, 1991, 1992 Craig Durland
  6.  *   Distributed under the terms of the GNU General Public License.
  7.  *   Distributed "as is", without warranties of any kind, but comments,
  8.  *     suggestions and bug reports are welcome.
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <os.h>
  13. #include <const.h>
  14. #include <dtable.h>
  15. #include "mc.h"
  16. #include "mm.h"
  17. #include "opcode.h"
  18.  
  19. extern char ebuf[], *malloc(), *savestr(), *spoof();
  20.  
  21. /***********************************************************************
  22. ********************* Token tables *************************************
  23. ***********************************************************************/
  24.  
  25. MuttCmd
  26.     /* holes: 22, 30, 32-41, 44-59, 74 */
  27.   muttcmds[] =        /* biggest # = 81 */
  28.   {
  29.     "!=",        0,
  30.     "*",        65,
  31.     "*=",        66,
  32.     "+",        3,
  33.     "+=",        63,
  34.     "-",        67,
  35.     "-=",        68,
  36.     "/",        69,
  37.     "/=",        70,
  38.     "<",        11,
  39.     "<=",        10,
  40.     "==",        12,
  41.     ">",        13,
  42.     ">=",        14,
  43.     "and",        80,
  44.     "arg",        43,
  45.     "array",        73,
  46.     "ask-user",        26,
  47.     "bool",        62,
  48.     "break",        7,
  49.     "byte",        75,
  50.     "cond",        1,
  51.     "const",        77,
  52.     "continue",        71,
  53.     "convert-to",    20,
  54.     "defun",        2,
  55.     "done",        9,
  56.     "extract-element",    24,
  57.     "extract-elements",    25,
  58.     "floc",        78,
  59.     "for",        76,
  60.     "goto",        6,
  61.     "halt",        16,
  62.     "if",        23,
  63.     "include",        64,
  64.     "insert-object",    18,
  65.     "int",        31,
  66.     "label",        8,
  67.     "length-of",    19,
  68.     "list",        27,
  69.     "loc",        79,
  70.     "nargs",        42,
  71.     "not",        28,
  72.     "novalue",        29,
  73.     "or",        81,
  74.     "pointer",        72,
  75.     "push-arg",        17,
  76.     "push-args",    15,
  77.     "remove-elements",    21,
  78.     "small-int",    61,
  79.     "string",        60,
  80.     "switch",        4,
  81.     "while",        5,
  82.   },
  83.   modifiers[] =            /* the pgm modifiers */
  84.   {
  85.     "HIDDEN",    HIDDEN,
  86.     "MAIN",    MAIN,
  87.   };
  88.  
  89. oMuttCmd
  90.   omuttcmds[] =        /* the other Mutt commands, see other_Mutt_cmd() */
  91.   {
  92.     "ask",        ASK,        STRING,
  93.     "concat",        CONCAT,        STRING,
  94.     "extract-element",    EXTRACT_EL, UNKNOWN,
  95.     "extract-elements",    EXTRACT_ELS,UNKNOWN, /* !!!actually, same as first arg */
  96.     "insert-object",    INSERT_OBJ, UNKNOWN,
  97.     "msg",        MSG,        STRING,
  98.     "remove-elements",    REMOVE_ELS, VOID,
  99.   };
  100.  
  101. int
  102.   msize = NITEMS(muttcmds),
  103.   omsize = NITEMS(omuttcmds), moders = NITEMS(modifiers);
  104.  
  105.  
  106. /* ******************************************************************** */
  107. /* ************************* External Tokens ************************** */
  108. /* ******************************************************************** */
  109.  
  110. /*
  111.  * A token table is stored in a file.
  112.  *   Format:
  113.  *     <token number> <token name>
  114.  */
  115.  
  116. static declare_and_init_dTable(ext_token_table,MuttCmd);
  117. static int num_ext_tokens = 0;
  118.  
  119. void load_ext_token_table(fname) char *fname;
  120. {
  121.   char buf[90], *ptr;
  122.   int t;
  123.   FILE *fptr;
  124.  
  125.   new_ext(buf,fname,".tok");
  126.   if ((fptr = fopen(buf,"r")) == NULL)
  127.     bitch(spoof(ebuf,"Can't open token file %s!",buf));
  128.  
  129.   while ((ptr = fgets(buf,80,fptr)))
  130.   {
  131.     if (!xpand_dTable(&ext_token_table, 1, 100,50))
  132.     {
  133.       printf("Out of memory! Can't expand external token table.\n");
  134.       exit(1);
  135.     }
  136.     buf[strlen(buf)-1] = '\0';
  137.     t = atoi(ptr); while (*ptr++!=' ') ;
  138.     if (NULL == (ptr = savestr(ptr)))
  139.     bail("Can't malloc external token name");
  140.  
  141.     ext_token_table.table[num_ext_tokens].name  = ptr;
  142.     ext_token_table.table[num_ext_tokens].token = t;
  143.     num_ext_tokens++;
  144.   }
  145. }
  146.  
  147.     /* Look for an external token by name.  Returns value.
  148.      * Input:
  149.      *   name:  name of the token to search for.  If NULL, search by value.
  150.      * Returns:  
  151.      *   -1 : name not found.
  152.      *   val : token value.
  153.      */
  154. lookup_ext_token_by_name(name) char *name;
  155. {
  156.   return lookup(name, ext_token_table.table, num_ext_tokens);
  157. }
  158.  
  159.     /* Look for an external token by value.  Returns name.
  160.      * Input:
  161.      *   val:  token value to search for if name is NULL.
  162.      * Returns:
  163.      *   NULL : val not found
  164.      *   pointer to the token name
  165.      */
  166. char *lookup_ext_token_by_value(val)
  167. {
  168.   int j;
  169.  
  170.   for (j = 0; j < num_ext_tokens; j++)
  171.     if (ext_token_table.table[j].token == val)
  172.     return ext_token_table.table[j].name;
  173.  
  174.   return NULL;
  175. }
  176.  
  177.  
  178. /* ******************************************************************** */
  179. /* ******************* Mutt Table Look Up Routines ******************** */
  180. /* ******************************************************************** */
  181.  
  182.     /* Use binary search table to find name
  183.      * returns: token (if name in table) else -1
  184.      */
  185. /* ??? use bsearch */
  186. lookup(name,table,n) char *name; MuttCmd *table;
  187. {
  188.   register int  j, lower = 0, upper = n-1, x;
  189.  
  190.   while (lower <= upper)
  191.   {
  192.     j = (lower+upper)/2;
  193.     if ((x = strcmp(name,table[j].name))>0) lower = j +1;
  194.     else if (x<0) upper = j -1; else return table[j].token;
  195.   }
  196.   return -1;
  197. }
  198.  
  199. /* ??? use bsearch */
  200. oMuttCmd *olookup(name,table,n) char *name; oMuttCmd *table;
  201. {
  202.   register int  j, lower = 0, upper = n-1, x;
  203.  
  204.   while (lower<=upper)
  205.   {
  206.     j = (lower+upper)/2;
  207.     if ((x = strcmp(name,table[j].name))>0) lower = j +1;
  208.     else if (x<0) upper = j -1; else return &table[j];
  209.   }
  210.   return NULL;
  211. }
  212.  
  213. /***********************************************************************
  214. ********************* Conversion routines ******************************
  215. ***********************************************************************/
  216.  
  217. int32 atoN(a) char *a;        /* convert string to NUMBER */
  218. {
  219.   char c, *b=a;
  220.   int minus = FALSE, base = 10, z;
  221.   int32 n = 0;
  222.  
  223.   if (*a == '-') { a++; minus = TRUE; }
  224.   if (*a == '0' && a[1] == 'x') { base = 16; a += 2; }
  225.   for (; *a; a++)
  226.   {
  227.     c = *a; z = 1000;
  228.     if ('0' <= c && c <= '9') z = c -'0';
  229.     else
  230.       if      ('a' <= c && c <= 'f') z = c -'a' +10;
  231.       else if ('A' <= c && c <= 'F') z = c -'A' +10;
  232.     if (z >= base) { moan(spoof(ebuf,"Invalid digit in %s",b)); break; }
  233.     n = n*base +z;
  234.   }
  235.   return minus ? -n : n;
  236. }
  237.  
  238. /***********************************************************************
  239. ********************* Scanning routines ********************************
  240. ***********************************************************************/
  241.  
  242. #include <ctype.h>
  243.  
  244. extern char token[];            /* in mc.c */
  245. extern FILE *lstfile, *srcfile;        /* in mc.c */
  246. extern int srcline;            /* in mc.c */
  247. extern unsigned int class;
  248.  
  249. static char pgmtext[514], *xptr;
  250. static int looked = FALSE;
  251. static unsigned int proclass;
  252.  
  253. int btv = FALSE;    /* boolean token value - returned by get_token() */
  254.  
  255.     /* move the pc to the next nonwhite character
  256.      * returns: TRUE if ok, FALSE if EoF
  257.      */
  258. getsrc()
  259. {
  260.   char *ptr;
  261.  
  262.   if ((xptr = fgets(pgmtext,512,srcfile)) == NULL) return FALSE;
  263.   if (*(ptr = xptr + strlen(xptr) -1) == '\n') *ptr = '\0';
  264.   srcline++;
  265.   if (lstfile) fprintf(lstfile,"LINE %d: %s\n",srcline,xptr);
  266.   return TRUE;
  267. }
  268.  
  269.     /* skip comment => skip to next line */
  270.     /* EoF: Ok if comment is last thing in buffer/file */
  271. #define nocomment() getsrc()
  272.  
  273. static scan()
  274. {
  275. top:    /* incase got to get a new line */
  276.   while (isspace(*xptr)) xptr++;    /* delete leading white space */
  277.   if (*xptr == '\0' || *xptr == '\n')
  278.     if (getsrc()) goto top; else return FALSE;
  279.   if (*xptr == ';') if (nocomment()) goto top; else return FALSE;
  280.   return TRUE;
  281. }
  282.  
  283.     /* returns: TRUE (all ok), FALSE (something screwed up)
  284.      */
  285. void get_token()
  286. {
  287.   register char *ptr;
  288.  
  289.   if (looked) { looked = FALSE; class = proclass; return; }
  290.  
  291.   *(ptr = token) = '\0'; class = TOKEN;
  292.   if (!scan()) { class = proclass = SEOF; return; }
  293.   switch (*xptr)
  294.   {
  295.     case '\'':        /* string literal: 'string', ''=>' */
  296.       for (xptr++; *xptr && ptr < (token +250); xptr++)
  297.     if (*xptr == '\'' && *++xptr != '\'') goto uggg;
  298.     else *ptr++ = *xptr;
  299.       if (*xptr == '\0') bitch("String not terminated!");
  300.     uggg:
  301.       class = STRING;
  302.       break;
  303.     case '\"':        /* "string": knows about \ (quote), ^ (control) */
  304.       for (xptr++; *xptr && *xptr != '\"' && ptr < (token +250); xptr++)
  305.     switch (*xptr)
  306.     {
  307.       case '\\': *ptr++ = *++xptr; break;    /* \ : quote next char */
  308.       case '^':  *ptr++ = *++xptr ^ 0x40; break;    /* ^ => cntl char */
  309.       default:   *ptr++ = *xptr;
  310.     }
  311.       if (*xptr == '\0') bitch("String not terminated!");
  312.       xptr++; class = STRING;
  313.       break;
  314.     default:    /* get a token or number */
  315.       while (*xptr && !isspace(*xptr))
  316.       {
  317.     if (strchr("(){};",*xptr))
  318.     {
  319.       if (ptr == token) { class = DELIMITER; *ptr++ = *xptr++; }
  320.       break;
  321.     }
  322.     *ptr++ = *xptr++;
  323.       }
  324.   }
  325.   *ptr = '\0';
  326.   if (class == TOKEN)
  327.   {
  328.     if ((isdigit(*token) || (*token == '-' && isdigit(*(token+1)))))
  329.     class = NUMBER;
  330.     else if (strcmp(token,"FALSE") == 0)     { class = BOOLEAN; btv = FALSE; }
  331.      else if (strcmp(token,"TRUE") == 0) { class = BOOLEAN; btv = TRUE; }
  332.   }
  333.   proclass = class;
  334.   return;
  335. }
  336.  
  337.     /* Note: gotta be careful class don't get trashed between
  338.      *   lookahead() & get_token()
  339.      */
  340. void lookahead()
  341. {
  342.   if (looked) { class = proclass; return; }
  343.   get_token(); looked = TRUE;
  344. }
  345.  
  346. typedef struct Inca { struct Inca *next; char fname[1]; } Inca;
  347. static Inca *inchead = NULL;
  348.  
  349. include(fname) char *fname;
  350. {
  351.   register Inca *ptr;
  352.  
  353.   for (ptr = inchead; ptr; ptr = ptr->next)
  354.     if (strcmp(ptr->fname,fname) == 0)
  355.     {
  356.       gripe(spoof(ebuf,"Already included: %s.  Ignoring.",fname));
  357.       nocomment();    /* bloto rest of line */
  358.       return UNKNOWN;
  359.     }
  360.   if (NULL == (ptr = (Inca *)malloc(sizeof(Inca) +strlen(fname))))
  361.     bail("Out of memory in include()");
  362.   strcpy(ptr->fname,fname);
  363.   ptr->next = inchead; inchead = ptr;
  364.   pilefile(fname,TRUE);
  365.   getsrc();    /* prime scan() */
  366.  
  367.   return UNKNOWN;
  368. }
  369.